package com.aurigalogic.weatherPortlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.portlet.GenericPortlet;
import javax.portlet.ActionRequest;
import javax.portlet.RenderRequest;
import javax.portlet.ActionResponse;
import javax.portlet.RenderResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletRequest;
import javax.portlet.PortletURL;
import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;
import javax.portlet.WindowState;
import javax.portlet.ValidatorException;

import org.apache.log4j.Logger;

public class WeatherPortlet extends GenericPortlet {

    private static Logger log = Logger.getLogger(WeatherPortlet.class);
    private static final String DEFAULT_CITY = "Mumbai, India";
    private static final String DEFAULT_FORECAST_DAYS = "2";
    private static final String DEFAULT_UNIT = "m";
    private static final PortletMode CUSTOM_CONFIG_MODE = new PortletMode("about");

    public void init() throws PortletException {
        WeatherService.init(getPortletConfig().getInitParameter("proxyHost"),
                getPortletConfig().getInitParameter("proxyPort"));
    }

    public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {
        PortletMode portletMode = PortletMode.VIEW;
        PortletPreferences pref = request.getPreferences();
        String cityName = request.getParameter("cityName");
        pref.setValue("cityName", cityName);
        String unit = request.getParameter("unit");
        if (unit == null || (unit != null && unit.equals(""))) {
            pref.setValue("unit", "KMS");
        } else {
            pref.setValue("unit", unit);
        }
        String forecast = request.getParameter("forecastDays");
        if (forecast == null || (forecast != null && forecast.equals(""))) {
            pref.setValue("forecastDays", "1");
        } else {
            pref.setValue("forecastDays", request.getParameter("forecastDays"));
        }
        try {
            pref.store();
        } catch (ValidatorException ve) {
            response.setRenderParameter("cityName", cityName);
            portletMode = PortletMode.EDIT;
        }
        response.setPortletMode(portletMode);
    }

    public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
        PortletPreferences pref = request.getPreferences();
        String cityName = pref.getValue("cityName", DEFAULT_CITY);
        java.util.Map parameters = new java.util.HashMap(3);
        parameters.put("unit", pref.getValue("unit", DEFAULT_UNIT));
        parameters.put("key", pref.getValue("key", null));
        parameters.put("par", pref.getValue("par", null));
        parameters.put("forecastDays", pref.getValue("forecastDays", DEFAULT_FORECAST_DAYS));
        try {
            Weather weatherInfo = WeatherService.getInstance().getWeatherByCity(cityName, parameters);
            request.setAttribute("weatherInfo", weatherInfo);
            response.setTitle("Weather for " + weatherInfo.getLocation());
        } catch (IOException ioe) {
            request.setAttribute("errorMessage", "error.communication");
            log.error("Exception while fetching weather", ioe);
        }
        response.setContentType(request.getResponseContentType());
        PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/view.jsp");
        dispatcher.include(request, response);
    }

    public void doEdit(RenderRequest request, RenderResponse response) throws PortletException, IOException {
        PortletPreferences pref = request.getPreferences();

        String cityName = request.getParameter("cityName");
        if (cityName == null) {
            cityName = pref.getValue("cityName", DEFAULT_CITY);
        } else {
            String errorMessage = null;
            // either no cities or too many cities were found.
            try {
                List locations = WeatherService.getInstance().loadLocations(cityName);
                if (locations.size() == 0) {
                    errorMessage = "error.cityNotFound";
                } else {
                    errorMessage = "error.multipleCitiesFound";
                    request.setAttribute("locations", locations);
                }
            } catch (IOException ioe) {
                log.error("Exception while fetching locations", ioe);
                errorMessage = "error.communication";
            }
            request.setAttribute("errorMessage", errorMessage);
        }
        request.setAttribute("cityName", cityName);
        request.setAttribute("unit", pref.getValue("unit", DEFAULT_UNIT));
        request.setAttribute("forecastDays", pref.getValue("forecastDays", DEFAULT_FORECAST_DAYS));
        response.setContentType(request.getResponseContentType());

        PortletURL url = response.createActionURL();
        url.setParameter("view", "showCityInfo");
        url.setParameter("cityName", cityName);
        url.setPortletMode(PortletMode.VIEW);
        url.setWindowState(WindowState.NORMAL);
        String szurl = url.toString();
        request.setAttribute("cityDetailUrl", szurl);

        PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/edit.jsp");
        dispatcher.include(request, response);
    }

    protected void doDispatch(RenderRequest request, RenderResponse response) throws PortletException, IOException {
        if (!WindowState.MINIMIZED.equals(request.getWindowState())) {
            PortletMode mode = request.getPortletMode();
            if (CUSTOM_CONFIG_MODE.equals(mode)) {
                doCustomConfigure(request, response);
                return;
            }
        }
        super.doDispatch(request, response);
    }

    private void doCustomConfigure(RenderRequest request, RenderResponse response) throws PortletException, IOException {
        response.setContentType(request.getResponseContentType());
        PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/about.jsp");
        dispatcher.include(request, response);
    }
}
